package com.note.notes.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.note.common.constants.ResponseCodeConstants;
import com.note.common.domain.Note;
import com.note.common.dto.NoteDto;
import com.note.common.dto.group.NoteGroup;
import com.note.common.enums.LogEnum;
import com.note.common.enums.ResponseEnum;
import com.note.common.interfaces.SystemLog;
import com.note.common.vo.ResponseVo;
import com.note.config.config.CustomBlockHandler;
import com.note.notes.pojo.NoteUpdatePojo;
import com.note.notes.service.NoteService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Package：com.note.notes.controller
 * @Name：NoteController
 * @Author：热伊木
 * @Email：uyevan@163.com
 * @Date：2023-12-20-14:52
 * @Description：笔记本体控制类
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/note")
@Tag(name = "NoteController", description = "笔记操作相关接口")
public class NoteController {

    @Autowired
    private NoteService noteService;

    /*记录笔记|获取笔记列表|获取笔记内容|更新笔记|删除笔记*/

    @ResponseBody
    @PostMapping("/recordNote")
    @SystemLog(type = LogEnum.SAVE_LOG)
    @Operation(summary = "recordNote", description = "记录新笔记")
    public ResponseVo recordNote(@RequestBody @Validated({NoteGroup.class}) NoteDto noteDto) {
        /*创建笔记*/
        int recordStatus = noteService.recordNote(noteDto);
        return switch (recordStatus) {
            case ResponseCodeConstants.DONT_EXISTS_FOLDER -> new ResponseVo(ResponseEnum.DONT_EXISTS_FOLDER);
            case ResponseCodeConstants.NOTE_RECORD_SUCCESS -> new ResponseVo(ResponseEnum.NOTE_REPORT_SUCCESS);
            default -> new ResponseVo(ResponseEnum.NOTE_REPORT_FAIL);
        };
    }

    @ResponseBody
    @GetMapping("/listNotes")
    @SystemLog(type = LogEnum.CHECK_LOG)
    @Operation(summary = "listNotes", description = "获取笔记列表")
    @Parameters({
            @Parameter(name = "username", description = "用户名", required = true, in = ParameterIn.QUERY),
            @Parameter(name = "folderId", description = "所属文件夹Id", required = true, in = ParameterIn.QUERY)
    })
    public ResponseVo listNotes(
            @RequestParam @NotBlank(message = "用户名不能为空") String username,
            @RequestParam @NotBlank(message = "目录ID不能为空") String folderId) {
        return new ResponseVo<>(ResponseEnum.SUCCESS, noteService.listNotes(folderId, username));
    }

    @ResponseBody
    @GetMapping("/viewNote")
    @SystemLog(type = LogEnum.CHECK_LOG)
    @Operation(summary = "viewNote", description = "查看笔记")
    @Parameters({
            @Parameter(name = "username", description = "用户名", required = true, in = ParameterIn.QUERY),
            @Parameter(name = "noteId", description = "所查看笔记Id", required = true, in = ParameterIn.QUERY)
    })
    public ResponseVo viewNote(
            @RequestParam @NotBlank(message = "用户名不能为空") String username,
            @RequestParam @NotBlank(message = "笔记ID不能为空") String noteId) {
        return new ResponseVo<>(ResponseEnum.SUCCESS, noteService.viewNote(noteId, username));
    }

    @ResponseBody
    @PutMapping("/updateNote")
    @SystemLog(type = LogEnum.REFRESH_LOG)
    @Operation(summary = "updateNote", description = "更新笔记内容")
    public ResponseVo updateNote(@RequestBody @Validated({NoteGroup.class}) NoteUpdatePojo noteUpdatePojo) {
        /*更新笔记*/
        int updateStatus = noteService.updateNote(noteUpdatePojo);
        return switch (updateStatus) {
            case ResponseCodeConstants.DONT_EXISTS_NOTE -> new ResponseVo(ResponseEnum.DONT_EXITS_NOTE);
            case ResponseCodeConstants.DONT_EXISTS_FOLDER -> new ResponseVo(ResponseEnum.DONT_EXISTS_FOLDER);
            case ResponseCodeConstants.UPDATE_NOTE_SUCCESS -> new ResponseVo(ResponseEnum.UPDATE_NOTE_SUCCESS);
            default -> new ResponseVo(ResponseEnum.FAIL);
        };
    }

    @ResponseBody
    @DeleteMapping("/removeNote")
    @SystemLog(type = LogEnum.REMOVE_LOG)
    @Operation(summary = "removeNote", description = "删除笔记")
    @Parameters({
            @Parameter(name = "username", description = "用户名", required = true, in = ParameterIn.QUERY),
            @Parameter(name = "noteId", description = "所删除笔记Id", required = true, in = ParameterIn.QUERY)
    })
    public ResponseVo removeNote(
            @RequestParam @NotBlank(message = "用户名不能为空") String username,
            @RequestParam @NotBlank(message = "笔记ID不能为空") String noteId) {
        /*删除笔记*/
        int removeStatus = noteService.removeNote(noteId, username);
        return switch (removeStatus) {
            case ResponseCodeConstants.DONT_EXISTS_NOTE -> new ResponseVo(ResponseEnum.DONT_EXITS_NOTE);
            case ResponseCodeConstants.REMOVE_NOTE_SUCCESS -> new ResponseVo(ResponseEnum.REMOVE_NOTE_SUCCESS);
            default -> new ResponseVo(ResponseEnum.FAIL);
        };
    }

    @ResponseBody
    @GetMapping("/viewShareNote/{noteId}")
    @SystemLog(type = LogEnum.CHECK_LOG)
    @Operation(summary = "viewShareNote", description = "查看分享的笔记")
    @SentinelResource(value = "viewShareNote",
            blockHandler = "blockHandleException",
            blockHandlerClass = CustomBlockHandler.class,
            fallbackClass = CustomBlockHandler.class,
            fallback = "fallBackHandle")
    @Parameters({
            @Parameter(name = "noteId", description = "笔记Id", required = true, in = ParameterIn.QUERY)
    })
    public ResponseVo viewShareNote(@PathVariable("noteId") @NotBlank(message = "笔记ID不能为空") String noteId) {
        return new ResponseVo<>(ResponseEnum.SUCCESS, noteService.viewShareNote(noteId));
    }

    @ResponseBody
    @GetMapping("/findNotes")
    @SystemLog(type = LogEnum.CHECK_LOG)
    @Operation(summary = "findNotes", description = "搜索笔记")
    @SentinelResource(value = "findNotes",
            blockHandler = "blockHandleException",
            blockHandlerClass = CustomBlockHandler.class,
            fallbackClass = CustomBlockHandler.class,
            fallback = "fallBackHandle")
    @Parameters({
            @Parameter(name = "username", description = "用户名", required = true, in = ParameterIn.QUERY),
            @Parameter(name = "keyword", description = "搜索关键字", required = true, in = ParameterIn.QUERY)
    })
    public ResponseVo findNotes(@RequestParam @NotBlank(message = "用户名不能为空") String username,
                                @RequestParam @NotBlank(message = "搜索关键字不能为空") String keyword) {
        List<Note> notes = noteService.findNotes(username, keyword);
        if (notes.isEmpty()) {
            return new ResponseVo(ResponseEnum.NOTE_SEARCH_FAIL, null);
        }
        ResponseVo responseVo = new ResponseVo(ResponseEnum.NOTE_SEARCH_SUCCESS, notes);
        responseVo.setMessage("查到 %d 条笔记啦".formatted(notes.size()));
        return responseVo;
    }
}
